<div class="toc-box right-motion">
  <div class="toc-wrapper <%= site.customConfig.autoNumber?'auto-number':'' %> <%= site.customConfig.tocCompress%>" id="toc_wrapper">
    <%- toc %>
  </div>
</div>

<script>

let lastTop = 0, lList = [], hList = [], postBody, lastIndex = -1; 
let active = 'active-show', activeClass = 'active-current';
let tocWrapper = document.querySelector('#toc_wrapper');
let tocContent = tocWrapper.children[0];
let autoNumber = tocWrapper&&tocWrapper.classList.contains('auto-number');

function addTocNumber(elem, deep) {
  if (!elem) {
    return;
  }
  let prop = elem.__proto__;

  if (prop === HTMLUListElement.prototype) {
    for (let i = 0; i < elem.children.length; i++) {
      addTocNumber(elem.children[i], deep + (i + 1) + '.');
    }
  } else if (prop === HTMLLIElement.prototype) {
    // 保存li元素
    lList.push(elem);
    for (let i = 0; i < elem.children.length; i++) {
      let cur = elem.children[i];
      if (cur.__proto__ === HTMLAnchorElement.prototype) {
        if (autoNumber) {
          cur.text =  deep + ' ' + cur.text;
        }
      } else if (cur.__proto__ === HTMLUListElement.prototype) {
        addTocNumber(cur, deep);
      }
    }
  }
}


document.addEventListener('scroll', function(e) {
  if (lList.length <= 0) {
    return;
  }
  let scrollTop = document.scrollingElement.scrollTop;
  let dir;

  if (lastTop - scrollTop > 0) {
    dir = 'up';
  } else {
    dir = 'down';
  }

  lastTop = scrollTop;
  if (scrollTop <= 0) {
    if (lastIndex >= 0 && lastIndex < hList.length) {
      lList[lastIndex].classList.remove(activeClass);
    }
    return;
  }

  let current = 0, hasFind = false;
  for (let i = 0; i < hList.length; i++) {
    if (hList[i].offsetTop > scrollTop) {
      current = i;
      hasFind = true;
      break;
    }
  }
  if (!hasFind && scrollTop > lList[lList.length - 1].offsetTop) {
    current = hList.length - 1;
  } else {
    current--;
  }
  if (dir === 'down') {
    if (current > lastIndex) {
      addActiveClass(current);
      removeActiveClass(lastIndex) 
      lastIndex = current;
      removeParentActiveClass();
      lList[current] && addActiveLiElemment(lList[current].parentElement,tocContent);
    }
  } else {
    if (current < lastIndex) {
      addActiveClass(current);
      removeActiveClass(lastIndex);
      lastIndex = current;
      removeParentActiveClass();
      lList[current] && addActiveLiElemment(lList[current].parentElement,tocContent);
    }
  }
});

function removeParentActiveClass() {
  let parents = tocContent.querySelectorAll('.'+active)
  parents.forEach(function(elem) {
    elem.classList.remove(active);
  });
}

function addActiveClass(index) {
  if (index >= 0 && index < hList.length) {
    lList[index].classList.add(activeClass);
  }
}

function removeActiveClass(index) {
  if (index >= 0 && index < hList.length) {
    lList[index].classList.remove(activeClass);
  }
}

function addActiveLiElemment(elem, parent) {
  if (!elem || elem === parent) {
    return;
  } else {
    if (elem.__proto__ === HTMLLIElement.prototype) {
      elem.classList.add(active);
    }
    addActiveLiElemment(elem.parentElement, parent);
  }
}

function showToc() {
  if (tocWrapper) {
    postBody = document.querySelector('#post_body');
    for (let i = 0; i < postBody.children.length; i++) {
      if (postBody.children[i].__proto__ === HTMLHeadingElement.prototype) {
        hList.push(postBody.children[i]);
      }
    }
    if (tocWrapper.classList.contains('compress')) {
        tocContent.classList.add('closed');
    } else if (tocWrapper.classList.contains('no_compress')){
      tocContent.classList.add('expanded');
    } else {
      if (hList.length > 10) {
        active = 'active-hidden'
        tocContent.classList.add('closed');
      } else {
        tocContent.classList.add('expanded');
      }
    }
  }
}
addTocNumber(tocContent, '');

window.addEventListener('load', function() {
  showToc();
  document.querySelector('#sidebar').style='display: block;';
  tocWrapper.classList.add('toc-active');
  setTimeout(function() {
    if ("createEvent" in document) {
      let evt = document.createEvent("HTMLEvents");
      evt.initEvent("scroll", false, true);
      document.dispatchEvent(evt);
    }
    else {
      document.fireEvent("scroll");
    }
  }, 500)
})

</script>